package com.rul.mars.order.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.rul.mars.common.constant.DeleteStatusConstant;
import com.rul.mars.common.constant.LeaseStatusConstant;
import com.rul.mars.common.constant.PickupTypeConstant;
import com.rul.mars.common.exception.Asserts;
import com.rul.mars.common.service.RedisService;
import com.rul.mars.mbg.domain.LeaseDetail;
import com.rul.mars.mbg.domain.LeaseParam;
import com.rul.mars.mbg.domain.ReceiveAddressDetail;
import com.rul.mars.mbg.mapper.LeaseMapper;
import com.rul.mars.mbg.mapper.ProductMapper;
import com.rul.mars.mbg.model.Lease;
import com.rul.mars.mbg.model.Product;
import com.rul.mars.mbg.model.User;
import com.rul.mars.order.service.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * 租赁服务实现
 *
 * @author RuL
 */
@Service
public class LeaseServiceImpl implements LeaseService {

    @Autowired
    private LeaseMapper leaseMapper;
    @Autowired
    private ProductMapper productMapper;

    @Autowired
    private UserService userService;
    @Autowired
    private UserAddressService userAddressService;

    @Autowired
    private StockService stockService;
    @Autowired
    private RedisService redisService;

    @Value("${redis.key.leaseId}")
    private String REDIS_KEY_LEASE_ID;
    @Value("${redis.database}")
    private String REDIS_DATABASE;

    @Override
    public LeaseDetail detail(Long id) {
        Lease lease = leaseMapper.selectByPrimaryKey(id);
        return BeanUtil.copyProperties(lease, LeaseDetail.class);
    }

    @Override
    public LeaseDetail generateLease(LeaseParam leaseParam) {
        //当前用户
        User user = userService.currentUser();
        //商品信息
        Product product = productMapper.selectByPrimaryKey(leaseParam.getProductId());
        //需租赁的商品数量
        Integer productNumber = leaseParam.getProductNumber();

        if (product.getStock() < productNumber) {
            Asserts.fail("库存不足");
        } else {
            //锁定库存
            stockService.lockStock(product.getId(), productNumber);
        }

        //LeaseParam转为LeaseDetail
        Lease lease = BeanUtil.copyProperties(leaseParam, Lease.class);

        //单位租金（每件每天）
        BigDecimal rentPrice = product.getRentPrice();
        BigDecimal totalAmount = rentPrice
                .multiply(new BigDecimal(productNumber))
                .multiply(new BigDecimal(leaseParam.getRentDays()))
                //押金
                .add(new BigDecimal(productNumber).multiply(product.getDeposit()));

        if (leaseParam.getPickupType() == PickupTypeConstant.DELIVERY) {
            //送货上门
            totalAmount = totalAmount.add(product.getFreightAmount());
            //设置运费
            lease.setFreightAmount(product.getFreightAmount());
        }

        //收货地址
        ReceiveAddressDetail addressDetail = userAddressService.detail(leaseParam.getReceiveAddressId());
        lease.setReceiverName(addressDetail.getName());
        lease.setReceiverPhone(addressDetail.getPhoneNumber());
        lease.setReceiverProvince(addressDetail.getProvince());
        lease.setReceiverCity(addressDetail.getCity());
        lease.setReceiverRegion(addressDetail.getRegion());
        lease.setReceiverDetailAddress(addressDetail.getDetailAddress());

        //设置总金额
        lease.setTotalAmount(totalAmount);
        //设置单位租金
        lease.setUnitRent(rentPrice);
        //设置押金
        lease.setDepositAmount(new BigDecimal(productNumber).multiply(product.getDeposit()));


        //设置用户ID
        lease.setUserId(user.getId());
        //状态为未支付
        lease.setLeaseStatus(LeaseStatusConstant.NON_PAYMENT);
        //设置租赁单编号
        lease.setLeaseSn(generateOrderSn(lease));
        //设置店铺ID
        lease.setShopId(product.getShopId());

        leaseMapper.insertSelective(lease);
        return BeanUtil.copyProperties(lease, LeaseDetail.class);
    }

    /**
     * 取消租赁
     *
     * @param id 租赁单ID
     * @return 取消结果
     */
    @Override
    public boolean cancelLease(Long id) {
        Lease lease = leaseMapper.selectByPrimaryKey(id);
        lease.setLeaseStatus(LeaseStatusConstant.CANCELED);
        int rows = leaseMapper.updateByPrimaryKeySelective(lease);

        if (rows == 1) {
            //解锁库存
            stockService.unlockStock(lease.getProductId(), lease.getProductNumber());
            return true;
        }
        return false;
    }

    /**
     * 删除租赁
     *
     * @param id 租赁单ID
     * @return 删除结果
     */
    @Override
    public boolean deleteLease(Long id) {
        Lease lease = leaseMapper.selectByPrimaryKey(id);

        if (lease.getLeaseStatus() < LeaseStatusConstant.RECEIVED) {
            Asserts.fail("不能删除未收货的租赁单");
        }
        //设置删除状态为已删除
        lease.setDeleteStatus(DeleteStatusConstant.YES);
        int rows = leaseMapper.updateByPrimaryKeySelective(lease);
        return rows == 1;
    }

    /**
     * 用户确认收货
     *
     * @param id 租赁单ID
     * @return 收货结果
     */
    @Override
    public boolean confirmReceive(Long id) {
        Lease lease = leaseMapper.selectByPrimaryKey(id);
        //设置租赁单状态为已收货
        lease.setLeaseStatus(LeaseStatusConstant.RECEIVED);
        int rows = leaseMapper.updateByPrimaryKeySelective(lease);
        return rows == 1;
    }

    /**
     * 生成18位订单编号:8位日期+2位取件方式+2位支付方式+6位以上自增id
     *
     * @param lease 订单
     * @return 18位订单编号
     */
    private String generateOrderSn(Lease lease) {
        StringBuilder sb = new StringBuilder();
        String date = new SimpleDateFormat("yyyyMMdd").format(new Date());
        String key = REDIS_DATABASE + REDIS_KEY_LEASE_ID + date;
        Long increment = redisService.incr(key, 1);
        sb.append(date);
        sb.append(String.format("%02d", lease.getPickupType()));
        sb.append(String.format("%02d", lease.getPayType()));
        String incrementStr = increment.toString();
        if (incrementStr.length() <= 6) {
            sb.append(String.format("%06d", increment));
        } else {
            sb.append(incrementStr);
        }
        return sb.toString();
    }


}
